package com.cqhz.quwan.util;

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author whamu2
 * @date 2018/6/12
 */
public class PreferenceHelper {
    private static final String TAG = PreferenceHelper.class.getSimpleName();

    private static PreferenceHelper sInstance;
    private final SharedPreferences mPreferences;

    private PreferenceHelper(@NonNull final Context context) {
        mPreferences = PreferenceManager.getDefaultSharedPreferences(context);
    }

    public static PreferenceHelper getInstance(@NonNull final Context context) {
        if (sInstance == null) {
            sInstance = new PreferenceHelper(context.getApplicationContext());
        }
        return sInstance;
    }

    public void registerOnSharedPreferenceChangedListener(SharedPreferences.OnSharedPreferenceChangeListener l) {
        mPreferences.registerOnSharedPreferenceChangeListener(l);
    }

    public void unregisterOnSharedPreferenceChangedListener(SharedPreferences.OnSharedPreferenceChangeListener l) {
        mPreferences.unregisterOnSharedPreferenceChangeListener(l);
    }


    /**
     * Save entity class
     *
     * @param key Alias
     * @param val objects
     * @param <T> object class
     */
    public <T> void putObject(@NonNull String key, T val) {
        final SharedPreferences.Editor editor = mPreferences.edit();
        editor.putString(key, new Gson().toJson(val));
        editor.apply();
    }

    /**
     * Get entity class
     *
     * @param key   Alias，Consistent with the above
     * @param clazz objects class
     * @param <T>   objects class
     * @return object
     */
    public final <T> T getObject(@NonNull String key, Class<T> clazz) {
        String s = mPreferences.getString(key, "");
        Gson gson = new Gson();
        return gson.fromJson(s, clazz);
    }

    /**
     * Save collections
     *
     * @param key Alias
     * @param val list of object
     * @param <T> object
     */
    public <T> void putCollections(@NonNull String key, List<T> val) {
        final SharedPreferences.Editor editor = mPreferences.edit();
        String json = new Gson().toJson(val, new TypeToken<ArrayList<T>>() {
        }.getType());
        editor.putString(key, json);
        editor.apply();
    }

    /**
     * Get collections
     *
     * @param key   Alias
     * @param clazz object of class
     * @param <T>   object
     * @return list
     */
    public final <T> List<T> getCollections(@NonNull String key, Class<T> clazz) {
        String s = mPreferences.getString(key, "");
        Gson gson = new Gson();

        Type type = new TypeToken<ArrayList<JsonObject>>() {
        }.getType();
        ArrayList<JsonObject> jsonObjects = gson.fromJson(s, type);

        List<T> data = new ArrayList<>();
        if (jsonObjects != null && jsonObjects.size() > 0) {
            for (JsonObject jsonObject : jsonObjects) {
                data.add(gson.fromJson(jsonObject, clazz));
            }
        }

        return data;
    }

    /**
     * save integer
     *
     * @param key Alias
     * @param var type of integer
     */
    public void putInt(@NonNull String key, int var) {
        final SharedPreferences.Editor editor = mPreferences.edit();
        editor.putInt(key, var);
        editor.apply();
    }

    /**
     * get integer
     *
     * @param key      Alias
     * @param defValue type of integer to default
     * @return integer
     */
    public final int getInt(@NonNull String key, int defValue) {
        return mPreferences.getInt(key, defValue);
    }

    /**
     * save string
     *
     * @param key Alias
     * @param var type of string
     */
    public void putString(@NonNull String key, String var) {
        SharedPreferences.Editor editor = mPreferences.edit();
        editor.putString(key, var);
        editor.apply();
    }

    /**
     * get string
     *
     * @param key      Alias
     * @param defValue type of string to default
     * @return string
     */
    public final String getString(@NonNull String key, String defValue) {
        return mPreferences.getString(key, defValue);
    }

    /**
     * save long
     *
     * @param key Alias
     * @param var type of long
     */
    public void putLong(@NonNull String key, long var) {
        SharedPreferences.Editor editor = mPreferences.edit();
        editor.putLong(key, var);
        editor.apply();
    }

    /**
     * get long
     *
     * @param key      Alias
     * @param defValue type of long to default
     * @return long
     */
    public final long getLong(@NonNull String key, long defValue) {
        return mPreferences.getLong(key, defValue);
    }

    /**
     * save float
     *
     * @param key Alias
     * @param var type of float
     */
    public void putFloat(@NonNull String key, float var) {
        SharedPreferences.Editor editor = mPreferences.edit();
        editor.putFloat(key, var);
        editor.apply();
    }

    /**
     * get float
     *
     * @param key      Alias
     * @param defValue type of long to default
     * @return float
     */
    public final float getFloat(@NonNull String key, float defValue) {
        return mPreferences.getFloat(key, defValue);
    }

    /**
     * save boolean
     *
     * @param key Alias
     * @param var type of boolean
     */
    public void putBoolean(@NonNull String key, boolean var) {
        SharedPreferences.Editor editor = mPreferences.edit();
        editor.putBoolean(key, var);
        editor.apply();
    }

    /**
     * get boolean
     *
     * @param key      Alias
     * @param defValue type of boolean to default
     * @return boolean
     */
    public final boolean getBoolean(@NonNull String key, boolean defValue) {
        return mPreferences.getBoolean(key, defValue);
    }

    /**
     * save set
     *
     * @param key Alias
     * @param val type of set
     */
    public void putStringSet(@NonNull String key, Set<String> val) {
        final SharedPreferences.Editor editor = mPreferences.edit();
        editor.putStringSet(key, val);
        editor.apply();
    }

    /**
     * get set
     *
     * @param key Alias
     * @return HashSet
     */
    public final Set<String> getStringSet(@NonNull String key) {
        return mPreferences.getStringSet(key, new HashSet<String>());
    }
}
